package com.raymond.client.handler;

import com.alibaba.fastjson.JSONObject;
import com.raymond.client.msg.BaseMessage;
import com.raymond.client.remoting.RemotingHelper;
import com.raymond.client.service.RecvHandlerProcessors;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;

/**
 * 接收业务处理
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2022-10-27 16:39
 */
public class RecvBusinessHandler extends SimpleChannelInboundHandler<BaseMessage> {
    private final static Logger logger = LoggerFactory.getLogger(RecvBusinessHandler.class);

    private RecvHandlerProcessors handlerStrategy;

    private ExecutorService executorService;

    public RecvBusinessHandler(RecvHandlerProcessors handlerStrategy, ExecutorService executorService) {
        this.handlerStrategy = handlerStrategy;
        this.executorService = executorService;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseMessage msg) throws Exception {
        Runnable runnable = () -> {
            try {
                BaseHandler<BaseMessage> baseHandler = handlerStrategy.getBaseHandler(msg.getCommandId());
                if (baseHandler == null) {
                    notCommandId(ctx, msg);
                    return;
                }
                baseHandler.channelRead(ctx, msg);
            } catch (Throwable e) {
                handlerException(ctx, msg, e);
            }
        };
        if (executorService == null) {
            runnable.run();
            return;
        }
        executorService.execute(runnable);
    }

    protected void notCommandId(ChannelHandlerContext ctx, BaseMessage msg) {
        final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
        logger.warn("找不到对应的handler,remoteAddress:{},commandId:{}", remoteAddress, msg.getCommandId());
    }

    protected void handlerException(ChannelHandlerContext ctx, BaseMessage msg, Throwable cause) {
        logger.error("调用业务方法异常,报文:{}", JSONObject.toJSONString(msg), cause);
    }
}
